﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Atmk.WaterMeter.EF;
using Atmk.WaterMeter.MIS.Base;
using Atmk.WaterMeter.MIS.Common;
using Atmk.WaterMeter.MIS.Commons;
using Atmk.WaterMeter.MIS.Commons.Interfaces;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic.Statistics;
using Atmk.WaterMeter.MIS.Commons.Utils;
using Atmk.WaterMeter.MIS.Commons.ViewModels;
using Atmk.WaterMeter.MIS.Commons.ViewModels.OwnerMeter;
using Atmk.WaterMeter.MIS.Datas;
using Atmk.WaterMeter.MIS.Entities;
using Atmk.WaterMeter.MIS.Entities.Enums;
using Atmk.WaterMeter.MIS.Entities.Models;
using Atmk.WaterMeter.MIS.Models.ModelPuls;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.CSharp.RuntimeBinder;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NLog;

namespace Atmk.WaterMeter.MIS.Controllers
{
    [Authorize]
    public class OwnerMeterController : BaseApiController
    {
        protected Logger _logger = LogManager.GetCurrentClassLogger();
        private readonly TokenHelper _tokenHelper;
        private readonly IBaseInfoLogic _baseStatistcsLogic;
        private readonly IOwnerMeterLogic _ownerMeterLogic;

        /// <inheritdoc />
        public OwnerMeterController(
            IBaseInfoLogic baseInfoLogic,
            IOwnerMeterLogic ownerMeterLogic,
            TokenHelper tokenHelper)
        {
            _baseStatistcsLogic = baseInfoLogic;
            _ownerMeterLogic = ownerMeterLogic;
            _tokenHelper = tokenHelper;
        }

        /// <summary>
        /// 必填项字段
        /// </summary>
        /// <returns></returns>
        [HttpGet("/api/{X-Version}/[controller]/Required")]
        public IActionResult RequiredFields()
        {
            //TODO:需要改为可通过外部配置的参数
            var required = new List<string>
            {
                "ownerName"
                //"priceName",
                //"priceId",
                //"longitude",
                //"latitude",
                //"elevation",
                //"meterNumber",
                //"collector",
                //"refillType",
                //"meterBottomNumber"
            };

            return Ok(new
            {
                errcode = 0,
                msg = "ok",
                data = new
                {
                    required
                }
            });
        }

        /// <summary>
        /// 获取水表类型
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult MeterState()
        {
            var token = _tokenHelper.GetTokenByHttpContext();

            BaseResult baseResult;
            try
            {
                baseResult = new EnumListResult
                {
                    errcode = 0,
                    msg = "ok",
                    list = Enum.GetNames(typeof(MeterDocumentState)).ToList()
                };
                return Ok(baseResult);
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                baseResult = new BaseResult
                {
                    errcode = 1,
                    msg = "获取失败"
                };
            }
            return Ok(baseResult);
        }

        /// <summary>
        /// 查询业主信息列表 OwnerMeter/Select
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Select([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            //根据用户获取片区编码集合进行匹配
            try
            {
                var aid = obj.aid.ToString();
                var page = Convert.ToInt32(obj.page.ToString());
                string nodeType = obj.nodeType == null ? "" : obj.nodeType.ToString();
                //var pageSize = Convert.ToInt32(obj.pageSize.ToString());
                var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);
                if (aid == token.payload.areaid)
                    aid = "";
                object file;
                int count = 0;
                if (nodeType == "3")
                {
                    file = _ownerMeterLogic.SelectOwner(aid, page, pageSize, out count);
                }
                else
                {
                    file = _ownerMeterLogic.Select(0, token.payload.areaid, aid, nodeType, page, pageSize, out count);
                }
                return Ok(new
                {
                    errcode = 0,
                    msg = "ok",
                    data = new
                    {
                        total = count,
                        pageSize,
                        file
                    }
                });
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        /// 查询业主信息列表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SelectSearch([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息

            //根据用户获取片区编码集合进行匹配
            try
            {
                var searchType = obj.searchType.ToString();
                string searchValue = obj.searchValue.ToString();
                string aid = obj.aid.ToString();
                var page = Convert.ToInt32(obj.page.ToString());
                //var meterState = Convert.ToInt32(obj.meterState.ToString());
                var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);
                string nodeType = obj.nodeType == null ? "" : obj.nodeType.ToString();
                var file = new List<object>();
                using (var _context = ContextBuilder.Build())
                {
                    var total_districts = _context.District.ToList();
                    //List<Meter> meters = null;
                    List<Owner> owners = null;
                    //项目水费列表
                    var PrcieSteps = _context.PrcieStep.Where(m => m.ProjectId.ToString() == token.payload.areaid).ToList();
                    if (searchType == "业主姓名")
                    {
                        owners = _context.Owner.Where(m => m.Name.Contains(searchValue)).ToList();
                        if (owners == null)
                            return Ok(new { errcode = 0, msg = "没有记录", data = new { total = 0, pageSize, file } });

                    }
                    if (searchType == "手机号码")
                    {
                        owners = _context.Owner.Where(m => m.Mobile.Contains(searchValue)).ToList();
                        if (owners == null)
                            return Ok(new { errcode = 0, msg = "没有记录", data = new { total = 0, pageSize, file } });
                    }
                    if (searchType == "表编号")
                    {
                        var meters = _context.Meter.Where(m => m.MeterNumber.Contains(searchValue)).ToList();
                        if (meters != null)
                        {
                            owners = _context.Owner.Where(m => meters.Select(m1 => m1.OwnerId).Contains(m.Id)).ToList();
                        }
                        else
                        {
                            return Ok(new { errcode = 0, msg = "没有记录", data = new { total = 0, pageSize, file } });
                        }
                    }
                    if (owners.Count>500)
                    {
                        return Ok(new { errcode = 0, msg = "查询关键字 不够精准！", data = new { total = 0, pageSize, file } });
                    }
                    
                    for (var i = 0; i < owners.Count; i++)
                    {
                        var meters = _context.Meter.Where(m => m.OwnerId == owners[i].Id).ToList();
                        var district = total_districts.First(m => m.Id == owners[i].DistrictId);
                        //json转对象
                        var temptest = ((dynamic)JsonConvert.DeserializeObject(owners[i].Memo));
                        #region MyRegion
                        //获取坐标类
                        //_mapRepository.CoordinatePoint(owner[0].Id.ToString(), CoordinateType.Owner, out var longitude,
                        // out var latitude, out var elevation);
                        //var mapParameter = mapParameters.FirstOrDefault(m => m.NodeId == owner[0].Id.ToString());
                        //if (mapParameter != null)
                        //{
                        //    longitude = mapParameter.Longitude;
                        //    latitude = mapParameter.Latitude;
                        //    elevation = mapParameter.Elevation;
                        //} 
                        #endregion
                        file.Add(new
                        {
                            districtId = district.Id.ToString(),
                            districtName = district.Name,
                            Owner = new
                            {
                                ownerId = owners[i].Id, //业主Id                
                                ownerName = owners[i].Name, //业主名称
                                owners[i].HouseNumber, //门牌号           
                                mobile = owners[i].Mobile, //手机号码
                                longitude = 0, //经度 double类型
                                latitude = 0, //纬度 double类型
                                elevation = 0, //高程(海拔)  double类型
                                ownerMessage = JsonConvert.DeserializeObject(owners[i].Memo)
                            },
                            WaterMeter = meters.Count < 1 ? new object() : new
                            {
                                meterId = meters[0].Id, //水表Id
                                MeterType = meters[0].MeterType, //表类型
                                meterNumber = string.Join("<br>", meters.Select(m => m.MeterNumber)), //表编号
                                refillType = meters[0].RefillType, //缴费方式
                                MeterState = meters[0].MeterState, //表状态  
                                priceId = meters[0].PrcieStepId,
                                //priceName = _stepTariffRepository.GetPriceName(meter[i].PrcieStepId),//水价
                                priceName = PrcieSteps.FirstOrDefault(m => m.Id.ToString() == meters[0].PrcieStepId)?.Name,//水价
                                Imei = meters[0].Imei,
                                meterDatas = new { collector = meters[0].Imei }
                                //meterDatas = string.IsNullOrWhiteSpace(meter[i].Memo)?"":JsonConvert.DeserializeObject(meter[i].Memo)
                            }
                        });
                    }
                    ////获取分页数据
                    //var pageList = PaginatedList<object>.Create(file.ToList(), page, pageSize);
                    return Ok(new { errcode = 0, msg = "ok", data = new { total = owners.Count(), pageSize = 100, file = file } });
                }
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        /// 添加业主信息及水表信息
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddOwner([FromBody] dynamic obj)
        {
            try
            {
                var token = _tokenHelper.GetTokenByHttpContext();
                if (obj == null)
                {
                    _logger.Debug("传入Josn数据为空");
                    return Ok(new { errcode = 1, msg = $"传入数据出错" });
                }
                var result = _ownerMeterLogic.InsertOwner(obj.districtId.ToString(), obj.owner, token, out string ErrorMessage);
                return Ok(result
                    ? new { errcode = 0, msg = "ok" }
                    : new { errcode = 1, msg = ErrorMessage });
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"添加信息失败"
                });
            }
        }

        /// <summary>
        /// 修改业主信息及水表信息
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UpdateOwnerMeter([FromBody] dynamic obj)
        {
            try
            {
                var result = _ownerMeterLogic.Update(obj.districtId.ToString(), obj.owner, out Exception exception);
                return Ok(result
                    ? new { errcode = 0, msg = "ok" }
                    : new { errcode = 1, msg = $"修改数据错误,错误:{exception.Message}" });
            }
            catch (RuntimeBinderException)
            {
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取数据错误"
                });
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        /// 删除业主及水表信息
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult DeleteOwnerMeter([FromBody] dynamic obj)
        {
            try
            {
                var result = _ownerMeterLogic.Delete(obj.userId.ToString(), obj.meterId.ToString(),
                    out Exception exception);
                return Ok(result
                    ? new { errcode = 0, msg = "ok" }
                    : new { errcode = 1, msg = $"删除数据错误,错误:{exception.Message}" });
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        /// 换表时查询列表
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult SelectQueryOwMe([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            //根据用户获取片区编码集合进行匹配
            try
            {
                var searchType = obj.searchType.ToString();
                var searchValue = obj.searchValue.ToString();
                var aid = obj.aid.ToString();
                var page = Convert.ToInt32(obj.page.ToString());
                using (var context = Datas.ContextBuilder.Build())
                {
                    //var pageSize = _baseStatistcsLogic.PageSize(token.payload.id);
                    var user = context.User.FirstOrDefault(s => s.Id.ToString() == token.payload.id);
                    if (user == null) throw new Exception("用户不存在");
                    var pageSize = user.PageLines;
                    string nodeType = obj.nodeType == null ? "" : obj.nodeType.ToString();
                    if (aid == token.payload.areaid)
                        aid = "";
                    var file = _ownerMeterLogic.Select(1, token.payload.areaid, aid, nodeType, page, pageSize, out int count, -1, searchType,
                        searchValue);
                    return Ok(new
                    {
                        errcode = 0,
                        msg = "ok",
                        data = new
                        {
                            total = count,
                            pageSize,
                            file
                        }
                    });
                }
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取数据错误,错误:{e.Message}"
                });
            }
        }

        /// <summary>
        /// 换表
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ChengOwnerMeter([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息

            //根据用户获取片区编码集合进行匹配
            try
            {
                //var result = MergeQureyMock.ChangeMeter(obj, out Exception exception);
                var result = _ownerMeterLogic.Exchange(token.payload.id, obj);
                return result
                    ? Ok(new
                    {
                        errcode = 0,
                        msg = "OK"
                    })
                    : Ok(new
                    {
                        errcode = 1,
                        msg = "换表失败"
                    });
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"换表失败:{e.Message}"
                });
            }
        }

        /// <summary>
        /// 销表
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult CancelMeter([FromBody] CancelMeter obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息

            //根据用户获取片区编码集合进行匹配
            try
            {
                var result = _ownerMeterLogic.Cancel(token.payload.id, obj);
                return result
                    ? Ok(new
                    {
                        errcode = 0,
                        msg = "OK"
                    })
                    : Ok(new
                    {
                        errcode = 1,
                        msg = "换表失败"
                    });
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"换表失败:{e.Message}"
                });
            }
        }


        /// <summary>
        /// 导出业主档案
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult OwnerExport([FromBody] dynamic obj)
        {
            var token = _tokenHelper.GetTokenByHttpContext();
            //验证用户信息
            //根据用户获取片区编码集合进行匹配
            try
            {
                using (var _context = ContextBuilder.Build())
                {
                    var orders = _context.OrderDetail.ToList();
                    var meters = _context.Meter.Where(m => m.ProjectId == token.payload.areaid);
                    var districts = _context.District.Where(m => m.ProjectId == token.payload.areaid).ToList();
                    var district_ids = districts.Select(m => m.Id).ToArray();
                    var owners = _context.Owner.Where(m => district_ids.Contains(m.DistrictId)).ToList();
                    var file = new List<object>();
                    foreach (var meter in meters)
                    {
                        dynamic obj_temp = new System.Dynamic.ExpandoObject();
                        obj_temp.district = districts.FirstOrDefault(m => m.Id == meter.DistrictId)?.Name;
                        obj_temp.ownerName = owners.FirstOrDefault(m => m.Id == meter.OwnerId)?.Name;
                        obj_temp.houseNumber = owners.FirstOrDefault(m => m.Id == meter.OwnerId)?.HouseNumber;
                        obj_temp.mobile = owners.FirstOrDefault(m => m.Id == meter.OwnerId)?.Mobile;
                        obj_temp.meterNumber = meter.MeterNumber;
                        obj_temp.balance = orders.Where(m => m.OwnerId == meter.OwnerId).Sum(n => n.Money);
                        file.Add(obj_temp);
                    }
                    return Ok(new
                    {
                        errcode = 0,
                        msg = "ok",
                        data = new
                        {
                            total = file.Count,
                            file
                        }
                    });
                }
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
                return Ok(new
                {
                    errcode = 1,
                    msg = $"获取数据错误,错误:{e.Message}"
                });
            }
        }
    }
}